//枚举类型  +函数指针 +结构体 实现状态机
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// 状态枚举
typedef enum {
    RED,
    GREEN,
    YELLOW
} TrafficLightState;
// 事件枚举
typedef enum {
    TIMEOUT
} Event;

// 状态机结构体  通过结构体可以修改灯的状态
typedef struct TrafficLight {
    TrafficLightState currentState;//存了一个当前的灯的状态
} TrafficLight;

//函数指针数组  分别指向了 三个状态对应的处理函数
void (*f_p[3])(Event event, struct TrafficLight *tl);
// 红灯状态处理函数    //事件       
void redStateHandler(Event event, TrafficLight *tl) {
    if (event == TIMEOUT) {
        printf("Red light timeout, switch to green light\n");
        tl->currentState = GREEN;//将状态变化为绿灯
    }
}
// 绿灯状态处理函数
void greenStateHandler(Event event, TrafficLight *tl) {
    if (event == TIMEOUT) {
        printf("Green light timeout, switch to yellow light\n");
        tl->currentState = YELLOW;
    }
}
// 黄灯状态处理函数
void yellowStateHandler(Event event, TrafficLight *tl) {
    if (event == TIMEOUT) {
        printf("Yellow light timeout, switch to red light\n");
        tl->currentState = RED;
    }
}



// 初始化状态机
void initTrafficLight(TrafficLight *tl) {
    tl->currentState = RED;//红灯
    //给函数指针数组 进行赋值
    f_p[0]=redStateHandler;
    f_p[1]=greenStateHandler;
    f_p[2]=yellowStateHandler;
}

// 处理事件
void handleEvent(TrafficLight *tl, Event event) {
    switch (tl->currentState) //灯的状态
    {//判断灯的状态
        case RED:
           f_p[0](event, tl);//通过函数指针来指向处理任务
            break;
        case GREEN:
            f_p[1](event, tl);
            break;
        case YELLOW:
            f_p[2](event, tl);
            break;
        default:
            break;
    }
}
void change(TrafficLight *t)
{
    t->currentState=GREEN;
}
int main() {


     TrafficLight tl;//交通灯  灯的状态，
     initTrafficLight(&tl);//初始化交通灯的状态 以及初始化函数指针的指向
     handleEvent(&tl, TIMEOUT);//处理事件
     while(1)
     {
      //  handleEvent(&tl, TIMEOUT);
        //  handleEvent(&tl, TIMEOUT);
        for(int i=10;i>=0;i--)
        {
            printf("%d\t",i);
            _sleep(1000);
            handleEvent(&tl, i);
        }
        printf("\n");
     }
     

    return 0;
}